package ch.unisi.inf.pfii.teamred.pacman.model;

import java.util.ArrayList;

import ch.unisi.inf.pfii.teamred.pacman.controller.PlayerListener;

/**
 * This class describes a player in the Pacman game.
 * 
 * @author luca.vignola@lu.unisi.ch
 * @author mark.pruneri@lu.unisi.ch
 */

public final class Player {

	private static final int DEFAULT_LIVES = 3;

	private final String name;
	private final Pacman pacman;
	private final ArrayList<PlayerListener> listeners;

	private int life;
	private int score;

	public Player(final String name, final Pacman pacman) {
		this.name = name;
		this.pacman = pacman;
		listeners = new ArrayList<PlayerListener>();
		life = DEFAULT_LIVES;
		score = 0;
	}

	public final void setScore(final int score) {
		this.score = score;
		firePlayerSetScore();
	}

	public final int getScore() {
		return score;
	}

	public final String getName() {
		return name;
	}

	public final void setLife(final int life) {
		this.life = life;
		firePlayerSetLife();
	}

	public final int getLife() {
		return life;
	}

	public final Pacman getPacman() {
		return pacman;
	}

	public final void setPacmanDirection(final Direction currentDirection) {
		pacman.setCurrentDirection(currentDirection);
	}

	private final void updateScore() {
		score += pacman.handlePoints();
		firePlayerUpdatedScore();
	}

	public final String getStatus() {
		return "Player: " + name + " Life: " + life + " Score: " + score + ".";
	}

	public final void reduceLifeByOne() {
		if (life == 0) {
			firePlayerIsDead();
		} else {
			life--;
		}
		firePlayerSetLife();
	}

	public final void updateStatus() {
		updateScore();
		pacman.updateStatus();
	}

	public final void addPlayerListener(final PlayerListener listener) {
		listeners.add(listener);
	}

	public final void removePlayerListener(final PlayerListener listener) {
		listeners.remove(listener);
	}

	private final void firePlayerSetScore() {
		for (final PlayerListener listener : listeners) {
			listener.playerSetScore(this);
		}
	}

	private final void firePlayerSetLife() {
		for (final PlayerListener listener : listeners) {
			listener.playerSetLife(this);
		}
	}

	private final void firePlayerUpdatedScore() {
		for (final PlayerListener listener : listeners) {
			listener.playerUpdatedScore(this);
		}
	}

	private final void firePlayerIsDead() {
		for (final PlayerListener listener : listeners) {
			listener.playerIsDead(this);
		}
	}
}
